package com.ntd.study.base.type;

import cn.hutool.core.lang.Console;

/**
 * 字符串相关学习
 */
public class StudyString {
    public void test() {
        String t = "abc";
        String str = "abcd";
        System.out.println(str == "abcd");
        System.out.println(str == new String("abcd"));
        System.out.println(str == t + "d");
        System.out.println(str == "abc" + "d");
        System.out.println(str == new String("abc") + "d");
    }

    public static void main(String[] args) {
        new StudyString().sort();
    }

    private void sort(){
        /**
         * -1，前一个数小
         * 0，两个数相等
         * 1，前一个数大
         */
        Console.log("10".compareTo("11"));
    }

    private void stringList() {
        /**
         * 1.性能差别：StringBuilder > StringBuffer > String
         * 2.String对字符串的操作（修改、拼接）其实是在创建新的对象，效率低下
         * 3.StringBuffer线程安全、StringBuilder线程不安全
         */
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("start");  // StringBuilder 使用示例(线程不安全)
        StringBuffer stringBuffer = new StringBuffer();
        stringBuffer.append("start");  // stringBuffer 使用示例（线程安全的）
        /**
         * String 使用详解
         */
        String str = "";
        String _str = new String();  // jdk 默认编译为这种
        /**
         * String 常用方法
         */
        str.length(); // 获取字符串长度
        str.substring(0, 1); // 字符串切割（从开始位置到指定位置，指定位置可选）
        str.startsWith("prefix"); // 判断字符串是否以 prefix 开头
        str.endsWith("suffix"); //判断字符串是否已 suffix 结尾
        str.indexOf("test"); // 查找指定字符串在原字符串中第一次出现的位置，找不到返回-1
        str.lastIndexOf("test"); // 查找指定字符串在原字符串中最后一次出现的位置，找不到返回-1
        str.contains("test"); // 判断是否包含某个字符串，返回true或false 参数为 CharSequence
        str.toCharArray(); // 将字符串转换为 字符数组 char[]
        str.toLowerCase(); // 将字符串转换为小写字符串
        str.toUpperCase(); // 将字符串转换为大写字符串
        str.getBytes(); // 获取字符串数组的 byte 序列（使用平台的默认编码），返回一个byte[] 数组
        str.equals("test"); // 字符串对比函数 对比字符串的值是否完全相等 ， 新手容易使用 str1 == "test"
        final boolean b = str == "test"; // 字符转 == 对比 ，因为字符串是引用类型，所有str本身存储的是内存地址（也可以理解为指针），这里的两个内存地址是不同的，所以不管如何都不会相等
        str.equalsIgnoreCase("test"); // 字符串对比，不考虑大小写
        str.trim(); // 去除字符串两端的空格，但是对于字符串中间的空格不进行处理 （注意：返回值去除，原字符串不变）
        final String[] strs = str.split(","); // 根据指定字符串进行切割，返回切割后的字符串数组
        /**
         * String 池 （独立于栈和堆之外的存在，存储不可变量） JDK 11
         * 每次创建 String 对象 （不创建String是不会去到常量池的） 将会去 String 池中寻找有没有相同对象，有的话直接返回引用，没有则创建并返回引用。
         */
        String string = "1"; // 第一次将会去 String 池创建对象，返回对象引用，string变量存储引用
        String string2 = "1"; // 给 string2 赋值的时候则直接 将 string2 的引用指向String 池中已经存在的 "1"，不在重新创建对象
        String string3 = "1" + "2"; //
        String string4 = "12"; // 创建 的 12 和 string3 是同一个存储地址，只有保存 string3的时候才会去到常量池
        String string5 = "1" + new String("3"); // 这个会在常量池中生成一个 3 的引用，在堆中生成一个 13 的引用，字符串对象的运算将会创建对象到堆中
        String string6 = string5.intern(); //  调用intern()方法将string字符串13添加到String池中，并返回String池引用

        /**
         * CharSequence
         * byte
         * Final
         * Serializable
         * Comparable
         */
    }
}
